﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Graphic = Ribbon.Core.Graphics.GraphicHelper;

namespace Ribbon.Core
{
    public class RibbonGroup
    {
        public RibbonGroup(string name)
        {
            this.Name = name;

            this.Text = name;

            this.GroupRect = new Rect(0, 0, 100, 200);

            this.Items = new RibbonItemCollection(this);

            this.BorderColor = Color.FromArgb(209, 209, 209);
        }

        public RibbonGroup(string name, string text)
            : this(name)
        {
            this.Text = text;
        }

        Rect groupRect;

        public Rect GroupRect
        {
            get
            {
                return groupRect;
            }
            set
            {
                groupRect = value;
            }
        }

        internal RibbonPage Parent { get; set; }

        public RibbonItemCollection Items { get; set; }

        public string Text { get; set; }

        public string Name { get; set; }

        private Font font;

        public Font Font
        {
            get
            {
                if (font == null)
                    return Parent.Font;
                else
                    return font;
            }
            set
            {
                font = value;

                if (value != null)
                {
                    foreach (IRibbonItem item in this.Items)
                    {
                        item.Font = value;
                    }
                }
            }
        }

        public int BorderSize { get; set; }

        public Color BorderColor { get; set; }

        public Color BackColor { get; set; }

        public Color ForeColor { get; set; }

        internal void Refresh()
        {
            this.Parent.Refresh();
        }

        internal void OnPaint(System.Drawing.Graphics g)
        {
            using (Pen p = new Pen(this.BorderColor, 1f))
            {
                g.DrawLine(p,
                    (int)(this.GroupRect.Width + this.GroupRect.X),
                    (int)(this.GroupRect.Y + 3),
                    (int)(this.GroupRect.Width + this.GroupRect.X),
                    (int)(this.GroupRect.Y + this.GroupRect.Height - 6));
            }

            foreach (IRibbonItem item in Items)
            {
                item.OnPaint(g);
            }
        }

        public event EventHandler Disposed;

        private ISite site;

        public ISite Site
        {
            get
            {
                return site;
            }
            set
            {
                site = value;
            }
        }

        public void Dispose()
        {
            if (Disposed != null)
                Disposed(this, new EventArgs());
        }
    }

    public class RibbonGroupCollection : IList<RibbonGroup>
    {
        private RibbonPage Parent { get; set; }

        private List<RibbonGroup> Groups;

        public RibbonGroupCollection(RibbonPage parent)
        {
            this.Parent = parent;

            this.Groups = new List<RibbonGroup>();
        }

        public int IndexOf(RibbonGroup item)
        {
            return Groups.IndexOf(item);
        }

        public void Insert(int index, RibbonGroup item)
        {
            Groups.Insert(index, item);
        }

        public void RemoveAt(int index)
        {
            Groups.RemoveAt(index);
        }

        public RibbonGroup this[int index]
        {
            get
            {
                return Groups[index];
            }
            set
            {
                Groups[index] = value;
            }
        }

        public void Add(RibbonGroup item)
        {
            item.Parent = this.Parent;

            float width = 0;

            for (int i = 0; i < Groups.Count; i++)
            {
                width += Groups[i].GroupRect.Width;
            }

            item.GroupRect = new Rect(width, this.Parent.Parent.TabHeight, 100, this.Parent.Parent.Height - this.Parent.Parent.TabHeight);

            Groups.Add(item);

            item.GroupRect.ValueChange += GroupRect_ValueChange;

            this.Parent.Refresh();
        }

        public void AddRange(params RibbonGroup[] items)
        {
            foreach (RibbonGroup item in items)
            {
                item.Parent = this.Parent;

                float width = 0;

                for (int i = 0; i < Groups.Count; i++)
                {
                    width += Groups[i].GroupRect.Width;
                }

                item.GroupRect = new Rect(width, this.Parent.Parent.TabHeight, 100, this.Parent.Parent.Height - this.Parent.Parent.TabHeight);

                Groups.Add(item);

                item.GroupRect.ValueChange += GroupRect_ValueChange;
            }

            this.Parent.Refresh();
        }

        void GroupRect_ValueChange(object OldValue, object NewValue)
        {
            float width = 0;

            for (int i = 0; i < Groups.Count; i++)
            {
                Groups[i].GroupRect.ValueChange -= GroupRect_ValueChange;

                Groups[i].GroupRect.X = width;

                width += Groups[i].GroupRect.Width;

                Groups[i].GroupRect.ValueChange += GroupRect_ValueChange;
            }
        }

        public void Clear()
        {
            Groups.Clear();
        }

        public bool Contains(RibbonGroup item)
        {
            return Groups.Contains(item);
        }

        public void CopyTo(RibbonGroup[] array, int arrayIndex)
        {
            Groups.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get { return Groups.Count; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        public bool Remove(RibbonGroup item)
        {
            return Groups.Remove(item);
        }

        public IEnumerator<RibbonGroup> GetEnumerator()
        {
            return Groups.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return Groups.GetEnumerator();
        }
    }
}
